using Admin.Application.Common;
using Admin.Application.Dto.User;
using Admin.Application.Repositories;
using Admin.Domain.Entities;
using Admin.Domain.Events;
using Admin.Domain.IEvents;
using Admin.Domain.Repositories;

namespace Admin.Application.Services;

public class AuthService(IRepository<User> userRepository, ITokenService jwtTokenService, ISystemLogRepository logService, IEventPublisher eventPublisher) : IAuthService
{
    private readonly IRepository<User> _userRepository = userRepository;
    private readonly ITokenService _jwtTokenService = jwtTokenService;
    private readonly ISystemLogRepository _logService = logService;
    private readonly IEventPublisher _eventPublisher = eventPublisher;

    public async Task<Result<string>> LoginAsync(AuthDto authDto)
    {
        var user = await _userRepository.GetOneConditionAsync(item => item.UserName == authDto.UserName);
        if (user == null)
        {
            await _logService.AddAsync($"登录失败：用户不存在 - {authDto.UserName}");
            return Result<string>.Fail("用户名或密码错误");
        }

        var isLogin = User.VerifyPasswordHash(user.PasswordSalt, authDto.Password, user.PasswordHash);
        if (!isLogin)
        {
            await _logService.AddAsync($"登录失败：密码错误 - {authDto.UserName}");
            return Result<string>.Fail("用户名或密码错误");
        }

        var token = _jwtTokenService.GenerateToken(user.Id, user.UserName);

        await _logService.AddAsync($"用户登录成功：{user.UserName}");

        return Result<string>.Success(token, "登录成功");
    }

    public async Task<Result<string>> RegisterAsync(AuthDto authDto)
    {
        var existingUser = await _userRepository.GetOneConditionAsync(item => item.UserName == authDto.UserName);
        if (existingUser != null)
        {
            await _logService.AddAsync($"注册失败：用户名已存在 - {authDto.UserName}");
            return Result<string>.Fail("用户已存在");
        }

        var user = User.CreateUser(authDto.UserName, authDto.Password);
        if (user == null)
        {
            await _logService.AddAsync($"注册失败：创建用户失败 - {authDto.UserName}");
            return Result<string>.Fail("用户注册失败");
        }

        await _userRepository.AddAsync(user);

        await _logService.AddAsync($"用户注册成功：{user.UserName}");

        await _eventPublisher.Publish(new UserCreatedEvent(user.Id, user.UserName));
        return Result<string>.Success(default, "用户注册成功");
    }
}